镜像仓库本地化方案 Registry(配置 Docker Hub 代理)
为什么需要私有镜像仓库
在 CI/CD 流水线中,容器化项目的构建产物是 Docker 镜像。将所有镜像推送到 Docker Hub 或阿里云并不总是可行,主要原因包括:
| 限制因素 | 说明 |
|---|---|
| 安全性 | 私密项目不宜暴露到公网仓库 |
| 经济性 | 阿里云个人版仅支持约 300 个私有仓库,超出需升级企业版 |
| 网络隔离 | 企业内网/政务网无法访问公网,需本地化存储 |
| 拉取限制 | Docker Hub 对匿名用户限制 100 次/6 小时,认证用户 200 次/6 小时 |
Docker 官方提供了 registry 镜像(CNCF Distribution 项目),可以快速搭建本地私有仓库。
截至当前,Registry(CNCF Distribution 项目)最新稳定版为 v3.1.1,项目已从 Docker 公司捐赠给 CNCF 基金会。
快速搭建本地 Registry
一行命令启动
docker run -d -p 5000:5000 --name registry registry:2
bash
启动后即可向 127.0.0.1:5000 推送和拉取镜像。
推送镜像到私有仓库
# 1. 为镜像打标签(指向私有仓库地址)
docker tag nginx:latest 127.0.0.1:5000/nginx:latest
# 2. 推送镜像
docker push 127.0.0.1:5000/nginx:latest
# 3. 查看仓库中的镜像列表
curl http://127.0.0.1:5000/v2/_catalog
bash
拉取私有仓库镜像
docker pull 127.0.0.1:5000/nginx:latest
bash
查看仓库中某个镜像的标签列表
curl http://127.0.0.1:5000/v2/nginx/tags/list
bash
输出示例:
{"name":"nginx","tags":["latest"]}
json
Docker Compose 部署(推荐)
生产环境推荐使用 Docker Compose 管理 Registry,便于配置持久化和自动重启:
# docker-compose.yml
version: "3.8"
services:
registry:
image: registry:2
container_name: private-registry
ports:
- "5000:5000"
volumes:
- registry-data:/var/lib/registry
- ./config.yml:/etc/docker/registry/config.yml
restart: unless-stopped
volumes:
registry-data:
yaml
启动与管理:
# 启动
docker compose up -d
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f registry
# 停止
docker compose down
bash
配置 Docker Hub 代理(镜像加速缓存)
Registry 可以配置为 Docker Hub 的 Pull-Through Cache(中转代理),充当镜像缓存站。客户端拉取镜像时,先从本地缓存获取;若不存在,则从 Docker Hub 拉取并缓存到本地。
工作原理
客户端 docker pull → 本地 Registry (缓存) → Docker Hub (远程)
↑ 缓存命中直接返回 ↓ 首次拉取后缓存
text
1. 查看 Registry 默认配置
在自定义配置之前,先查看 registry:2 镜像内置的默认配置:
docker run --rm registry:2 cat /etc/docker/registry/config.yml
bash
输出示例:
version: 0.1
log:
level: info
storage:
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: false
http:
addr: :5000
yaml
这一步很重要:自定义配置应基于默认配置进行扩展,而不是从头编写,否则可能出现
unsupported version等格式错误。
2. 创建 Registry 配置文件
sudo mkdir -p /etc/docker/registry
sudo vi /etc/docker/registry/config.yml
bash
配置内容:
# /etc/docker/registry/config.yml
version: 0.1
log:
level: info
storage:
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: :5000
proxy:
remoteurl: https://registry-1.docker.io
username: <your-docker-hub-username> # 可选,用于拉取私有镜像或提高限额
password: <your-docker-hub-password> # 建议使用 Personal Access Token
yaml
关键要点:
proxy部分是核心配置。remoteurl必须指向 Docker Hub 的官方 Registry 地址https://registry-1.docker.io,而不是https://hub.docker.com。建议配置 Docker Hub 账号认证,以获取更高的拉取限额。
3. 创建 Docker Hub Personal Access Token
在 Docker Hub 上创建访问令牌比直接使用密码更安全:
- 登录 Docker Hub
- 进入 Account Settings → Security → New Access Token
- 设置描述(如
registry-proxy)和权限(Read Only 即可) - 复制生成的 Token,填入
config.yml的password字段
4. 启动带代理配置的 Registry
# 停止并删除旧的 registry 容器
docker stop registry && docker rm registry
# 使用自定义配置启动
docker run -d \
-p 5000:5000 \
--name registry \
-v /etc/docker/registry/config.yml:/etc/docker/registry/config.yml \
registry:2
bash
验证容器正常启动:
docker ps | grep registry
# 如有异常,查看日志排查
docker logs registry
bash
5. 配置 Docker 客户端
编辑 /etc/docker/daemon.json(Docker Desktop 对应 Settings → Docker Engine 界面):
{
"registry-mirrors": ["http://127.0.0.1:5000"]
}
json
如果同时需要使用国内公共加速源,可以按优先级排列:
{ "registry-mirrors": [ "http://127.0.0.1:5000", "https://docker.1ms.run" ] }json
重启 Docker 服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
# macOS 上的 Docker Desktop 可手动重启
bash
6. 验证代理缓存
# 拉取一个本地不存在的镜像(如 node:22-alpine)
docker pull node:22-alpine
# 查看仓库目录,确认已被缓存
curl http://127.0.0.1:5000/v2/_catalog
bash
输出示例:
{"repositories":["library/node"]}
json
进一步查看该镜像的标签:
curl http://127.0.0.1:5000/v2/library/node/tags/list
bash
后续其他客户端再拉取相同镜像时,直接从本地 Registry 返回,速度大幅提升。
进阶:配置 TLS 证书
生产环境建议启用 HTTPS,避免在 daemon.json 中配置 insecure-registries:
# 生成自签名证书(测试用)
mkdir -p /certs
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout /certs/domain.key \
-x509 -days 365 \
-out /certs/domain.crt \
-subj "/CN=my-registry.local"
bash
通过 Docker Compose 启动带 TLS 的 Registry:
# docker-compose.tls.yml
version: "3.8"
services:
registry:
image: registry:2
container_name: private-registry
ports:
- "5000:5000"
volumes:
- registry-data:/var/lib/registry
- ./config.yml:/etc/docker/registry/config.yml
- ./certs:/certs
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
restart: unless-stopped
volumes:
registry-data:
yaml
客户端需要信任证书:
# Linux
sudo mkdir -p /etc/docker/certs.d/my-registry.local:5000
sudo cp /certs/domain.crt /etc/docker/certs.d/my-registry.local:5000/ca.crt
sudo systemctl restart docker
bash
配置 daemon.json 使用 HTTPS:
{
"registry-mirrors": ["https://my-registry.local:5000"]
}
json
进阶:配置用户认证
基于 htpasswd 的基础认证,适用于小团队场景:
1. 创建认证文件
# 创建认证目录
mkdir -p /auth
# 生成 htpasswd 文件(-B 使用 bcrypt 加密,-b 批量模式,-n 输出到 stdout)
docker run --rm --entrypoint htpasswd httpd:2 \
-Bbn admin mypassword > /auth/htpasswd
bash
2. 启动带认证的 Registry
docker run -d -p 5000:5000 \
--name registry \
-v /auth:/auth \
-v /etc/docker/registry/config.yml:/etc/docker/registry/config.yml \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
registry:2
bash
3. 登录与推送
# 登录私有仓库
docker login 127.0.0.1:5000 -u admin
# 输入密码后登录成功
# 推送镜像
docker push 127.0.0.1:5000/nginx:latest
bash
Registry 日常维护
垃圾回收
长期运行的 Registry 会积累未引用的层数据,需定期清理:
# 查看磁盘使用
du -sh /var/lib/registry
# 执行垃圾回收(干跑模式,仅查看不删除)
docker exec registry bin/registry garbage-collect \
--dry-run /etc/docker/registry/config.yml
# 执行垃圾回收(实际删除)
docker exec registry bin/registry garbage-collect \
/etc/docker/registry/config.yml
bash
注意:垃圾回收前,需要先通过 Registry API 删除不需要的镜像 manifest,然后才能回收对应的层数据。
删除镜像
# 1. 获取镜像的 digest
curl -I -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
http://127.0.0.1:5000/v2/nginx/manifests/latest
# 从返回头中获取 Docker-Content-Digest 值
# 2. 删除镜像 manifest
curl -X DELETE http://127.0.0.1:5000/v2/nginx/manifests/<digest>
# 3. 执行垃圾回收
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml
bash
定时清理(Cron)
# 每天凌晨 3 点执行垃圾回收
echo "0 3 * * * docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml" | sudo crontab -
bash
Docker Hub 拉取限制(2026 年最新)
Docker Hub 对不同用户等级施加了不同的拉取速率限制:
| 用户类型 | 拉取限制 | 价格 |
|---|---|---|
| 匿名(未登录) | 100 次 / 6 小时(按 IP 计算) | 免费 |
| Personal(免费认证) | 200 次 / 6 小时 | 免费 |
| Pro | 无限 | $5/月 |
| Team | 无限 | $7/用户/月起 |
| Business | 无限 | 自定义 |
配置本地代理缓存后,重复拉取走本地缓存,可显著减少对 Docker Hub 的请求次数。在 CI/CD 流水线中尤其重要——一条流水线每次构建可能拉取多个基础镜像,缓存后可以避免频繁触发限流。
国内镜像加速源参考(2026 年 5 月)
由于网络原因,国内访问 Docker Hub 经常超时。以下是当前可用的公共加速源(可用性随时变化,需定期验证):
| 镜像源 | 地址 | 说明 |
|---|---|---|
| 毫秒镜像 | https://docker.1ms.run | 免费、速度快、稳定 |
| 轩辕镜像 | https://docker.xuanyuan.me | 免费版 |
| 4hu 镜像 | https://registry.4hu.cn | 新兴稳定源 |
配置示例:
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
json
安全提醒:谨慎使用来源不明的加速源(尤其是托管在 GitHub Pages 或
*.pages.dev上的临时代理),可能存在镜像篡改风险。自建 Registry 代理是最安全的方案。
趋势:2024-2025 年间,中科大(USTC)、清华(TUNA)、网易等传统镜像站已陆续停止同步 Docker Hub,需关注社区动态获取最新可用源。
典型应用场景
企业内网镜像中转
┌──────────────┐ ┌───────────────────┐ ┌─────────────┐
│ 内网开发机器 │────→│ 中转服务器 Registry │────→│ Docker Hub │
│ docker pull │←────│ (可访问公网) │←────│ (公网仓库) │
└──────────────┘ └───────────────────┘ └─────────────┘
内网 缓存
text
- 一台可访问公网的服务器作为镜像中转
- 内网机器通过该服务器拉取和缓存镜像
- 后续拉取直接从本地缓存获取,速度快且节省带宽
CI/CD 流水线加速
# .gitlab-ci.yml 示例
build:
stage: build
image: 127.0.0.1:5000/node:22-alpine # 从本地 Registry 拉取
script:
- npm install
- npm run build
- docker build -t 127.0.0.1:5000/myapp:$CI_COMMIT_SHA .
- docker push 127.0.0.1:5000/myapp:$CI_COMMIT_SHA
yaml
多环境镜像分发
# 开发机构建并推送
docker build -t registry.internal:5000/app:v1.2.0 .
docker push registry.internal:5000/app:v1.2.0
# 测试环境拉取
docker pull registry.internal:5000/app:v1.2.0
# 生产环境拉取
docker pull registry.internal:5000/app:v1.2.0
bash
方案对比与选型
| 方案 | 适用场景 | 优势 | 不足 |
|---|---|---|---|
| Registry 基础版 | 内网私有仓库 | 部署简单,一行命令 | 无 UI,无权限管理 |
| Registry + 代理 | 镜像加速缓存 | 加速拉取,节省带宽 | 缺少图形化管理 |
| Registry + TLS + Auth | 生产环境 | 安全可靠 | 配置较复杂 |
| Harbor(下一节) | 企业级 | UI 完善、RBAC、镜像扫描 | 资源占用较大 |
如果需要图形化管理界面和更完善的权限控制,推荐使用下一节介绍的 Harbor 方案。
参考资源
↑